package com.honghe.web.controller.system;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.honghe.common.core.controller.BaseController;
import com.honghe.common.core.domain.AjaxResult;
import com.honghe.system.domain.vo.HandlerContactStatsResultVO;
import com.honghe.system.domain.vo.HandlerContactStatsVO;
import com.honghe.system.service.ICustomerContactStatsService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 负责人联系记录统计Controller
 */
@RestController
@RequestMapping("/system")
public class HandlerContactStatsController extends BaseController {
    private static final Logger log = LoggerFactory.getLogger(HandlerContactStatsController.class);

    @Autowired
    private ICustomerContactStatsService customerContactStatsService;
    
    @Autowired
    private JdbcTemplate jdbcTemplate;
    
    // 简单的数据缓存，避免频繁查询相同的数据
    private final Map<String, Object> dataCache = new ConcurrentHashMap<>();
    
    // 缓存过期时间（毫秒）- 5分钟
    private static final long CACHE_EXPIRE_TIME = TimeUnit.MINUTES.toMillis(5);
    
    // 缓存时间戳记录
    private final Map<String, Long> cacheTimestamps = new ConcurrentHashMap<>();

    /**
     * 获取负责人联系记录统计数据
     */
    @PreAuthorize("@ss.hasPermi('system:contact:list')")
    @GetMapping({"/contact/handler/stats", "/customer/contact/stats/handler"})
    public AjaxResult getHandlerStats(String[] dateRange, Integer pageNum, Integer pageSize, String handlerName) {
        long startTime = System.currentTimeMillis();
        log.info("接收请求 - 获取负责人联系记录统计数据，参数: dateRange={}, pageNum={}, pageSize={}, handlerName={}", 
                 Arrays.toString(dateRange), pageNum, pageSize, handlerName);
        
        try {
            // 构建缓存键 - 使用请求参数的哈希值
            String cacheKey = "stats_" + Arrays.hashCode(dateRange) + "_" + pageNum + "_" + pageSize + "_" + handlerName;
            
            // 检查缓存中是否有有效数据
            if (hasValidCache(cacheKey)) {
                HandlerContactStatsResultVO cachedResult = (HandlerContactStatsResultVO) dataCache.get(cacheKey);
                log.info("使用缓存数据 - 缓存键: {}, 执行时间: {}ms", cacheKey, System.currentTimeMillis() - startTime);
                return success(cachedResult);
            }
            
            // 参数处理 - 使用单一Map保存所有参数
            Map<String, Object> params = new HashMap<>();
            
            // 优化: 只添加非空参数
            if (pageNum != null) params.put("pageNum", pageNum);
            if (pageSize != null) params.put("pageSize", pageSize);
            if (handlerName != null && !handlerName.trim().isEmpty()) params.put("handlerName", handlerName);
            
            // 处理日期范围
            if (dateRange != null && dateRange.length == 2) {
                params.put("startDate", dateRange[0] + " 00:00:00");
                params.put("endDate", dateRange[1] + " 23:59:59");
                params.put("dateRange", dateRange);
            } else {
                // 如果没有提供日期范围，默认使用最近30天
                Calendar cal = Calendar.getInstance();
                java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                
                String endDate = sdf.format(cal.getTime());
                cal.add(Calendar.DAY_OF_MONTH, -30);
                String startDate = sdf.format(cal.getTime());
                
                params.put("startDate", startDate);
                params.put("endDate", endDate);
                params.put("dateRange", new String[]{startDate.substring(0, 10), endDate.substring(0, 10)});
            }

            // 性能监控 - 定期数据库检查，每小时只执行一次
            String dbCheckCacheKey = "db_check";
            if (!hasValidCache(dbCheckCacheKey)) {
                checkDatabaseStatistics();
                // 缓存检查结果，一小时内不再执行
                cacheData(dbCheckCacheKey, true, TimeUnit.HOURS.toMillis(1));
            }

            // 获取统计数据
            long serviceStartTime = System.currentTimeMillis();
            HandlerContactStatsResultVO result = customerContactStatsService.getHandlerContactStats(params);
            long serviceEndTime = System.currentTimeMillis();
            
            log.info("服务层处理时间: {}ms", serviceEndTime - serviceStartTime);
            
            // 检查结果并进行数据一致性验证
            if (result != null && result.getStatsList() != null && !result.getStatsList().isEmpty()) {
                log.info("获取到 {} 条负责人统计数据", result.getStatsList().size());
                
                // 使用批量处理而不是逐条遍历 - 缩短代码长度
                validateAndCorrectData(result.getStatsList());
                
                // 缓存处理后的结果
                cacheData(cacheKey, result, CACHE_EXPIRE_TIME);
                
                return success(result);
            } else {
                log.warn("未获取到负责人统计数据或结果为空");
                // 返回空结果
                HandlerContactStatsResultVO emptyResult = createEmptyResult();
                return success(emptyResult);
            }
        } catch (Exception e) {
            log.error("处理请求时发生错误", e);
            // 出错时返回空数据
            HandlerContactStatsResultVO emptyResult = createEmptyResult();
            return success(emptyResult);
        } finally {
            log.info("总处理时间: {}ms", System.currentTimeMillis() - startTime);
        }
    }
    
    /**
     * 验证和修正数据 - 确保未跟进客户数 + 已联系客户数 = 客户总数
     */
    private void validateAndCorrectData(List<Map<String, Object>> statsList) {
        for (Map<String, Object> stats : statsList) {
            try {
                // 提取数据用于计算
                int customerCount = getIntValue(stats, "customerCount");
                int contactedCustomerCount = getIntValue(stats, "contactedCustomerCount");
                int notFollowedCount = getIntValue(stats, "notFollowedCount");
                
                // 验证数据一致性: 客户总数 = 已联系客户数 + 未跟进客户数
                log.debug("数据一致性检查 - 负责人: {}, 客户总数: {}, 已联系客户数: {}, 未跟进客户数: {}, 和: {}", 
                        stats.get("handlerName"),
                        customerCount,
                        contactedCustomerCount, 
                        notFollowedCount,
                        contactedCustomerCount + notFollowedCount);
                
                // 如果等式不成立，记录警告并进行修正
                if (customerCount != contactedCustomerCount + notFollowedCount) {
                    int expectedNotFollowed = Math.max(0, customerCount - contactedCustomerCount);
                    log.warn("数据不一致 - 负责人: {}, 修正未跟进客户数: {} → {}", 
                            stats.get("handlerName"), notFollowedCount, expectedNotFollowed);
                    
                    // 修正数据
                    stats.put("notFollowedCount", expectedNotFollowed);
                }
            } catch (Exception e) {
                log.error("数据验证失败 - 负责人: {}, 错误: {}", stats.get("handlerName"), e.getMessage());
            }
        }
    }
    
    /**
     * 检查数据库统计信息 - 优化为单一高效查询
     */
    private void checkDatabaseStatistics() {
        try {
            log.info("执行数据库状态检查...");
            
            // 1. 基础表记录数量 - 使用单一高效查询
            List<Map<String, Object>> tableCounts = jdbcTemplate.queryForList(
                "SELECT 'users' as table_name, COUNT(*) as count FROM sys_user WHERE status = '0' UNION ALL " +
                "SELECT 'customers' as table_name, COUNT(*) as count FROM bank_customer_cases UNION ALL " +
                "SELECT 'contacts' as table_name, COUNT(*) as count FROM customer_contact_record"
            );
            
            Map<String, Integer> counts = new HashMap<>();
            for (Map<String, Object> row : tableCounts) {
                counts.put(row.get("table_name").toString(), 
                          ((Number)row.get("count")).intValue());
            }
            
            log.info("基础表记录数: 用户={}，客户={}，联系记录={}", 
                    counts.getOrDefault("users", 0),
                    counts.getOrDefault("customers", 0), 
                    counts.getOrDefault("contacts", 0));
            
            // 2. 执行数据一致性验证SQL - 只需一次查询
            List<Map<String, Object>> consistencyCheck = jdbcTemplate.queryForList(
                "SELECT " +
                "    h.case_handler, " +
                "    h.total_customers, " +
                "    h.contacted_customers, " +
                "    (h.total_customers - h.contacted_customers) as not_followed, " +
                "    (h.total_customers = h.contacted_customers + (h.total_customers - h.contacted_customers)) as is_valid " +
                "FROM (" +
                "    SELECT " +
                "        c.case_handler, " +
                "        COUNT(DISTINCT c.case_id) as total_customers, " +
                "        COUNT(DISTINCT CASE WHEN r.record_id IS NOT NULL THEN c.case_id END) as contacted_customers " +
                "    FROM bank_customer_cases c " +
                "    LEFT JOIN customer_contact_record r ON c.case_id = r.case_id " +
                "    WHERE c.case_handler IS NOT NULL AND c.case_handler != '' " +
                "    GROUP BY c.case_handler " +
                ") h " +
                "LIMIT 10"
            );
            
            if (!consistencyCheck.isEmpty()) {
                log.info("数据一致性检查 (前10条):");
                for (Map<String, Object> row : consistencyCheck) {
                    log.info("  负责人: {}, 客户数: {}, 已联系: {}, 未跟进: {}, 一致性: {}", 
                             row.get("case_handler"),
                             row.get("total_customers"),
                             row.get("contacted_customers"),
                             row.get("not_followed"),
                             row.get("is_valid"));
                }
            }
        } catch (Exception e) {
            log.error("数据库检查失败", e);
        }
    }
    
    /**
     * 获取Map中的整数值，安全处理各种类型
     */
    private int getIntValue(Map<String, Object> map, String key) {
        Object value = map.get(key);
        if (value == null) {
            return 0;
        }
        
        try {
            if (value instanceof Integer) {
                return (Integer) value;
            } else if (value instanceof Long) {
                return ((Long) value).intValue();
            } else {
                return Integer.parseInt(String.valueOf(value));
            }
        } catch (Exception e) {
            log.error("转换{}值时出错: {}", key, e.getMessage());
            return 0;
        }
    }
    
    /**
     * 创建空的结果对象
     */
    private HandlerContactStatsResultVO createEmptyResult() {
        HandlerContactStatsResultVO emptyResult = new HandlerContactStatsResultVO();
        emptyResult.setCode(200);
        emptyResult.setMsg("无数据");
        emptyResult.setStatsList(new ArrayList<>());
        
        HandlerContactStatsResultVO.TrendData emptyTrendData = new HandlerContactStatsResultVO.TrendData();
        emptyTrendData.setDates(new ArrayList<>());
        emptyTrendData.setHandlers(new ArrayList<>());
        emptyTrendData.setData(new HashMap<>());
        emptyResult.setTrendData(emptyTrendData);
        
        return emptyResult;
    }
    
    /**
     * 检查是否有有效的缓存数据
     */
    private boolean hasValidCache(String key) {
        if (!dataCache.containsKey(key)) {
            return false;
        }
        
        Long timestamp = cacheTimestamps.get(key);
        if (timestamp == null) {
            return false;
        }
        
        // 检查缓存是否过期
        return System.currentTimeMillis() - timestamp < CACHE_EXPIRE_TIME;
    }
    
    /**
     * 缓存数据
     */
    private void cacheData(String key, Object data, long expireTime) {
        dataCache.put(key, data);
        cacheTimestamps.put(key, System.currentTimeMillis());
        
        // 设置过期时间
        log.debug("缓存数据 - 键: {}, 过期时间: {}ms", key, expireTime);
    }
} 